﻿using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace System
{
    public class ExcelHelper
    {
        public static void ExportDataToExcelFile<T>(string strFilePath, List<T> data) where T : class
        {
            Type type = typeof(T);
            //获取工作表的名称
            string strSheetName = "sheet1";
            if (type.IsDefined(typeof(ExcelSheetAttribute), false))
            {
                ExcelSheetAttribute obj = (ExcelSheetAttribute)type.GetCustomAttributes(typeof(ExcelSheetAttribute), false)[0];
                strSheetName = obj.SheetName;
            }

            PropertyInfo[] props = type.GetProperties();
            CompareExcelProperty compareEP = new CompareExcelProperty();
            SortedDictionary<ExcelColumn, PropertyInfo> excelPropertyDic = new SortedDictionary<ExcelColumn, PropertyInfo>(compareEP);
            foreach (var prop in props)
            {
                object[] attrs = prop.GetCustomAttributes(false);
                foreach (var attr in attrs)
                {
                    ExcelColumn ec = attr as ExcelColumn;
                    if (ec != null)
                    {
                        excelPropertyDic.Add(ec, prop); //这里要求只有一个custom特性
                        break;
                    }
                }
            }
            var excelColumnList = excelPropertyDic.Keys.ToList();
            var propertyList = excelPropertyDic.Values.ToList();
            IWorkbook work = new HSSFWorkbook();
            ISheet sheet = work.CreateSheet(strSheetName);
            IRow header = sheet.CreateRow(0);
            for (int i = 0; i < excelPropertyDic.Count; i++)
            {
                header.CreateCell(i).SetCellValue(excelColumnList[i].ColumnName);
            }
            for (int i = 1; i <= data.Count; i++)
            {
                IRow row = sheet.CreateRow(i);
                for (int j = 0; j < excelPropertyDic.Count; j++)       //列数由拥有特性的属性个数决定，而不是属性个数，即类中没有标志ExcelColumn特性的属性不会写到文件中
                {
                    ICell cell = row.CreateCell(j);
                    cell.SetCellType(excelColumnList[j].ColumnType);
                    object value = propertyList[j].GetValue(data[i - 1], null);
                    if (value == null)
                    {
                        continue;
                    }
                    cell.SetCellValue(value.ToString());
                }
            }
            for (int i = 0; i < excelPropertyDic.Count; i++)
            {
                sheet.AutoSizeColumn(i, true);
            }
            FileStream fs = File.OpenWrite(strFilePath);
            work.Write(fs);
            fs.Close();
            work?.Dispose();
            work?.Close();
        }
    }

    public class CompareExcelProperty : IComparer<ExcelColumn>
    {
        public int Compare(ExcelColumn x, ExcelColumn y)
        {
            return x.Index > y.Index ? 1 : -1;
        }
    }
}
